﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// 
    /// </summary>
    public enum DEANAGLYPH
    {
        /// <summary>
        /// When composed using red and green
        /// </summary>
        RED_GREEN,

        /// <summary>
        /// When composes using red and cyan
        /// </summary>
        RED_CYAN,

        /// <summary>
        /// deanaglyph colored pics
        /// </summary>
        COLORED
    }

    /// <summary>
    /// This filter takes two images (normally) and renders an anaglyph pic.
    /// </summary>
    public class DeAnaglyph : BaseImageFilter, ITwoSourceFilter
    {
        protected Lambda m_LambdaRed = new Lambda("c.R, c.R, c.R");
        protected Lambda m_LambdaGreen = new Lambda("c.G, c.G, c.G");
        protected Lambda m_LambdaCyan = new Lambda("(c.G + c.B)/2, (c.G + c.B)/2, (c.G + c.B)/2");
        protected DEANAGLYPH m_MODE = DEANAGLYPH.RED_GREEN;

        private UnsafeBitmap m_BitmapLeft = null;
        private UnsafeBitmap m_BitmapRight = null;

        protected bool m_bGetOnlyRightResult = true;

        /// <summary>
        /// Initializes a new instance of the DeAnayglyph class.
        /// </summary>
        public DeAnaglyph()
        {
        }

        /// <summary>
        /// Initializes a new instance of the DeAnayglyph class.
        /// </summary>
        /// <param name="_anaglyph">The _anaglyph.</param>
        internal DeAnaglyph(DeAnaglyph _anaglyph)
        {
            m_MODE = _anaglyph.m_MODE;
        }

        /// <summary>
        /// Gets or sets mode
        /// </summary>
        public DEANAGLYPH MODE
        {
            get { return m_MODE; }
            set { m_MODE = value; }
        }

        /// <summary>
        /// Bitmap Left Result
        /// </summary>
        public UnsafeBitmap BitmapLeft
        {
            get { return m_BitmapLeft; }
        }

        /// <summary>
        /// Bitmap Right Result
        /// </summary>
        public UnsafeBitmap BitmapRight
        {
            get { return m_BitmapRight; }
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap1 = (UnsafeBitmap)_bitmap.Clone();
            UnsafeBitmap bitmap2 = (UnsafeBitmap)_bitmap.Clone();

            m_BitmapLeft = bitmap1;
            m_BitmapRight = bitmap2;
            switch(m_MODE)
            {
                case DEANAGLYPH.RED_GREEN:
                    m_LambdaGreen.Execute(bitmap1);
                    m_LambdaRed.Execute(bitmap2);
                    break;

                case DEANAGLYPH.RED_CYAN:
                    m_LambdaRed.Execute(bitmap1);
                    m_LambdaCyan.Execute(bitmap2);
                    break;

                case DEANAGLYPH.COLORED:
                    break;
            }
            return Process((UnsafeBitmap)_bitmap.Clone(), _bitmap);
        }

        #region ITwoSourceFilter Members

        /// <summary>
        /// Processes the specified _BMP source left.
        /// </summary>
        /// <param name="_bmpSourceLeft">The _BMP source left.</param>
        /// <param name="_bmpSourceRight">The _BMP source right.</param>
        /// <returns></returns>
        public UnsafeBitmap Process(UnsafeBitmap _bmpSourceLeft, UnsafeBitmap _bmpSourceRight)
        {
            //byte r1 = 0;
            //byte g1 = 0;
            //byte b1 = 0;
            //byte r2 = 0;
            //byte g2 = 0;
            //byte b2 = 0;
            //byte a = 0;
            //double r = 0;
            //double g = 0;
            //double b = 0;

            int nHeightLeft = _bmpSourceLeft.Height;
            int nWidthLeft = _bmpSourceLeft.Width;
            
            int nHeightRight = _bmpSourceRight.Height;
            int nWidthRight = _bmpSourceRight.Width;

            int x = 0;
            int y = 0;

            UnsafeBitmap bitmapResult = new UnsafeBitmap(new Bitmap(_bmpSourceRight.Width, _bmpSourceRight.Height));
            for (y = 0; y < nHeightLeft; y++)
            {
                for (x = 0; x < nWidthLeft; x++)
                {
                    //#Separate views & create manual or auto-levelled bitmaps
                    //Extract red channel
                    Color color = _bmpSourceRight.GetPixel(x, y);
                    _bmpSourceRight.SetPixelDirect(x, y, color.R, 0, 0);
                }
            }
            return _bmpSourceLeft;
        }

        #endregion

           //int x = 0;
           // int y = 0;
           // int nWidth = _bitmap.Width;
           // int nHeight = _bitmap.Height;

           // Color color = Color.Transparent;
           // UnsafeBitmap bitmapCloned = (UnsafeBitmap)_bitmap.Clone();
           // for (y = 0; y < nHeight; y++)
           // {
           //     int nLastX = 0;
           //     for (x = 0; x < nWidth; x++)
           //     {
           //         color = _bitmap.GetPixel(x, y);
           //         if (color == m_ColorForeground)
           //         {
           //             nLastX = x;
           //             color = Color.FromArgb(Math.Abs(x - nLastX) * 255);
           //         }
           //         _bitmap.SetPixel(x, y, nLastX != 0 ? color : ColorFunctions.GrayColor(color));
           //     }
           // }
           // return _bitmap;


        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new DeAnaglyph(this);
        }
    }
}
